﻿using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Net;
using System.Security;
using HtmlAgilityPack;
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Publishing;
using Microsoft.SharePoint.Client.Publishing.Navigation;
using Microsoft.SharePoint.Client.Taxonomy;


namespace SharePointOnlineCmdlets
{
    [RunInstaller(true)]   
    public class SPOCmdlets : PSSnapIn
    {
        public override string Name
        {
            get { return "SPOCmdlets"; }
        }

        public override string Vendor
        {
            get { return "Provoke Solutions"; }
        }

        public override string Description
        {
            get { return "Cmdlets for automating common tasks in SharePoint online"; }
        }
        
    }
   
    /// <summary>
    /// Installs a Web SCOPED FEATURE ONLY
    /// </summary>
    [Cmdlet(VerbsLifecycle.Install, "SPOWebFeature")]
    public class InstallSPOWebFeature : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Web Web { get; set; }

        [Parameter(Mandatory = true)]
        public string FeatureId { get; set; }

        [Parameter]
        public SwitchParameter Internal { get; set; }

        protected override void ProcessRecord()
        {
            var Context = Web.Context;
            var scope = Internal.IsPresent ? FeatureDefinitionScope.None : FeatureDefinitionScope.Site; //Internal activates with None.
            Web.Features.Add(new Guid(FeatureId), false, scope);
            Web.Update();

            Context.ExecuteQuery();
        }
    }


    /// <summary>
    /// Removes a Web SCOPED FEATURE ONLY
    /// </summary>
    [Cmdlet(VerbsLifecycle.Uninstall, "SPOWebFeature")]
    public class UnintallSPOFeature : Cmdlet
    {
        [Parameter(Mandatory = true)]
        public Web Web { get; set; }

        [Parameter(Mandatory = true)]
        public string FeatureId { get; set; }

        protected override void ProcessRecord()
        {
            var Context = Web.Context;
            Web.Features.Remove(new Guid(FeatureId), false);
            Web.Update();

            Context.ExecuteQuery();
        }
    }

    /// <summary>
    /// Installs a SITE SCOPED FEATURE ONLY
    /// </summary>
    [Cmdlet(VerbsLifecycle.Install, "SPOSiteFeature")]
    public class InstallSPOSiteFeature : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string FeatureId { get; set; }

        [Parameter]
        public SwitchParameter Internal { get; set; }

        protected override void ProcessRecord()
        {
            var Context = Site.Context;
            var scope = Internal.IsPresent ? FeatureDefinitionScope.None : FeatureDefinitionScope.Site; //internal features activate only when None is set.
            Site.Features.Add(new Guid(FeatureId), false, scope);

            Context.ExecuteQuery();
        }
    }

    /// <summary>
    /// Removes a SITE SCOPED FEATURE ONLY
    /// </summary>
    [Cmdlet(VerbsLifecycle.Uninstall, "SPOSiteFeature")]
    public class UninstallSPOSiteFeature : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string FeatureId { get; set; }

        protected override void ProcessRecord()
        {
            var Context = Site.Context;
            Site.Features.Remove(new Guid(FeatureId), false);
            Context.ExecuteQuery();
        }
    }

    /// <summary>
    /// Gets all features activated in the given site collection
    /// </summary>
    [Cmdlet(VerbsCommon.Get, "SPOSiteFeatures")]
    public class GetSPOSiteFeatures : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        protected override void ProcessRecord()
        {
            var Context = Site.Context;
            Context.Load(Site.Features);
            Context.ExecuteQuery();
            WriteObject(Site.Features);
        }
    }

    /// <summary>
    /// Gets a SharePointOnline Context. 
    /// </summary>
    [Cmdlet(VerbsCommon.Get, "SPOContext")]
    public class GetSPOContext : Cmdlet
    {
        [Parameter(Mandatory = true, Position = 0)]
        public string SiteUrl { get; set; }

        [Parameter(Mandatory = true, Position = 1)]
        public string UserName { get; set; }

        [Parameter(Mandatory = true, Position = 2)]
        public string Password { get; set; }

        protected override void ProcessRecord()
        {
            var pass = Password.ToCharArray();
            var secure = new SecureString();
            foreach (var ch in pass)
            {
                secure.AppendChar(ch);
            }

            ClientContext ctx = new ClientContext(SiteUrl);
            ctx.Credentials = new SharePointOnlineCredentials(UserName, secure);
            ctx.Load(ctx.Site);
            ctx.Load(ctx.Site.Owner);
            ctx.Load(ctx.Web);
            ctx.ExecuteQuery();
            WriteObject(ctx);

        }
    }

    /// <summary>
    /// Gets a SharePoint on Premise Context. 
    /// </summary>
    [Cmdlet(VerbsCommon.Get, "SPContext")]
    public class GetSPContext : Cmdlet
    {
        [Parameter(Mandatory = true, Position = 0)]
        public string SiteUrl { get; set; }

        [Parameter(Mandatory = true, Position = 1)]
        public string UserName { get; set; }

        [Parameter(Mandatory = true, Position = 2)]
        public string Password { get; set; }

        protected override void ProcessRecord()
        {
            var pass = Password.ToCharArray();
            var secure = new SecureString();
            foreach (var ch in pass)
            {
                secure.AppendChar(ch);
            }

            ClientContext ctx = new ClientContext(SiteUrl);
            ctx.Credentials = new NetworkCredential(UserName, secure);
            ctx.ExecuteQuery();
            WriteObject(ctx);

        }
    }

    

    /// <summary>
    /// Adds a SPO Solution to the solution gallery
    /// </summary>
    [Cmdlet(VerbsCommon.Add, "SPOSolution")]
    public class AddSPOSolution : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string FilePath { get; set; }

        protected override void ProcessRecord()
        {
            var ctx = (ClientContext)Site.Context;
            var fileUrl = Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/solutions/" + Path.GetFileName(FilePath);

            using (var fileStream = new FileStream(FilePath, FileMode.Open))
            {
                Microsoft.SharePoint.Client.File.SaveBinaryDirect(ctx, fileUrl, fileStream, true);
            }
            ctx.Load(Site);
            ctx.ExecuteQuery();
            WriteObject(Site);
        }
    }

    /// <summary>
    /// Removes a SPO Solution from the solution gallery
    /// </summary>
    [Cmdlet(VerbsCommon.Remove, "SPOSolution")]
    public class RemoveSPOSolution : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string Solution { get; set; }

        protected override void ProcessRecord()
        {
            var ctx = (ClientContext)Site.Context;
            var fileUrl = Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/solutions/" + Solution;
            var file = ctx.Web.GetFileByServerRelativeUrl(fileUrl);
            ctx.Load(file);
            ctx.ExecuteQuery();
            file.DeleteObject();
            ctx.ExecuteQuery();
            WriteObject(Site);
        }
    }

    /// <summary>
    /// Gets a list of all SPO Solutions in the solution gallery
    /// </summary>
    [Cmdlet(VerbsCommon.Get, "SPOSolutions")]
    public class GetSPOSolutions : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        protected override void ProcessRecord()
        {
            var ctx = (ClientContext)Site.Context;
            var folderUrl = Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/solutions/";
            var folder = Site.RootWeb.GetFolderByServerRelativeUrl(folderUrl);
            ctx.Load(folder.Files, collection => collection.Include(f => f.TimeLastModified, g => g.Name));
            ctx.ExecuteQuery();
            
            WriteObject(folder.Files);
        }
    }

    /// <summary>
    /// Downloads a SPO Solution from the solution gallery
    /// </summary>
    [Cmdlet(VerbsCommon.Get, "SPOSolution")]
    public class GetSPOSolution : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string Solution { get; set; }

        [Parameter]
        public string Path { get; set; }

        protected override void ProcessRecord()
        {
            Path = Path ?? ".";
            Path = Path.TrimEnd('\\').TrimEnd('/');
            var ctx = (ClientContext)Site.Context;
            var fileUrl = Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/solutions/" + Solution;
            var file = Microsoft.SharePoint.Client.File.OpenBinaryDirect(ctx, fileUrl);
            using(FileStream stream = new FileStream(Path +"/"+ Solution,FileMode.Create))
            {
                file.Stream.CopyTo(stream);
            }
            WriteObject(Site);
        }
    }

    /// <summary>
    /// Install and apply design package
    /// </summary>
    [Cmdlet(VerbsLifecycle.Install, "SPODesignPackage")]
    public class InstallSPODesignPackage : Cmdlet
    {
        [Parameter(Mandatory = true,ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string FileName { get; set; }

        [Parameter(Mandatory = true)]
        public string PackageName { get; set; }

        protected override void ProcessRecord()
        {
            //Create path to file name
            var dpackFile = Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/solutions/" + FileName;

            //Set design package info
            var info = new DesignPackageInfo();
            info.PackageName = PackageName;
            
            DesignPackage.Install(Site.Context, Site, info, dpackFile);
            Site.Context.ExecuteQuery();
            DesignPackage.Apply(Site.Context, Site, info);
            Site.Context.ExecuteQuery();
            WriteObject(info);
        }
    }

    /// <summary>
    /// Hooks up a lookup field to the specified list and sets the field to display
    /// </summary>
    [Cmdlet(VerbsCommon.Set, "SPOLookupField")]
    public class SetLookupField : Cmdlet
    {
        [Parameter(Mandatory = true)]
        public ClientContext Context { get; set; }

        [Parameter(Mandatory = true)]
        public string Web { get; set; }

        [Parameter(Mandatory = true)]
        public string Field { get; set; }

        [Parameter(Mandatory = true)]
        public string List { get; set; }

        [Parameter(Mandatory = true)]
        public string TargetField { get; set; }
        
        protected override void ProcessRecord()
        {
            var ctx = Context;
            
            var field = ctx.Site.RootWeb.Fields.GetByInternalNameOrTitle(Field);
            var webs = ctx.Site.RootWeb.Webs;
            ctx.Load(webs);
            ctx.ExecuteQuery();
            var web = webs.First(w => w.ServerRelativeUrl == Web);
           
            ctx.Load(field);
            ctx.Load(web);
            ctx.ExecuteQuery();
            var list = web.Lists.GetByTitle(List);
            ctx.Load(list, l => l.ContentTypes, j => j.Id);
            ctx.ExecuteQuery();
            var targetField = list.ContentTypes.First().Fields.GetByTitle(TargetField);
            ctx.Load(targetField);
            ctx.ExecuteQuery();
            FieldLookup lookup = new FieldLookup(ctx, field.Path);

            lookup.LookupWebId = web.Id;
            
            lookup.LookupList = list.Id.ToString();
            lookup.LookupField = TargetField;
            lookup.PrimaryFieldId = targetField.Id.ToString();
            lookup.UpdateAndPushChanges(true);

            ctx.Load(lookup);
            ctx.ExecuteQuery();
            base.ProcessRecord();
        }
    }

    /// <summary>
    /// Publishes all files within the specified folder/path.
    /// </summary>
    [Cmdlet(VerbsData.Publish, "SPOFiles")]
    public class PublishSPOFiles : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Web Web { get; set; }

        [Parameter(Mandatory = true)]
        public string FilePath { get; set; }

        protected override void ProcessRecord()
        {
            var ctx = (ClientContext)Web.Context;
            
            var folder = ctx.Web.GetFolderByServerRelativeUrl(FilePath);
            
            ctx.Load(folder.Files, collection => collection.Include(f => f.Name,x => x.CheckOutType));
            
            ctx.ExecuteQuery();
            foreach (var file in folder.Files)
            {
                if(file.Name == null) continue;
                if (!file.Name.Contains(".aspx") && !file.Name.Contains(".master"))
                {
                    if (file.CheckOutType == CheckOutType.None)
                    {
                        file.CheckOut();
                    }
                    file.CheckIn("Published", CheckinType.MajorCheckIn);
                    file.Publish("Published");
                }
                
            }
            
            ctx.ExecuteQuery();
           
        }
    }

    /// <summary>
    /// Publishes a single file given the path.
    /// </summary>
    [Cmdlet(VerbsData.Publish, "SPOFile")]
    public class PublishSPOFile : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Web Web { get; set; }

        [Parameter(Mandatory = true)]
        public string FilePath { get; set; }

        protected override void ProcessRecord()
        {
            var ctx = (ClientContext)Web.Context;

            var file = ctx.Web.GetFileByServerRelativeUrl(FilePath);

            ctx.Load(file);

            ctx.ExecuteQuery();
            if (!file.Name.Contains(".aspx") && !file.Name.Contains(".master"))
            {
                if (file.CheckOutType == CheckOutType.None)
                {
                    file.CheckOut();
                }
                file.CheckIn("Published", CheckinType.MajorCheckIn);
                file.Publish("Published");
            }

            ctx.ExecuteQuery();

        }
    }

    /// <summary>
    /// Sets navigation to inherit from the parent site.
    /// </summary>
    [Cmdlet(VerbsCommon.Set, "SPONavigationInherits")]
    public class SetSPONavigationInherits : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Web Web { get; set; }

        protected override void ProcessRecord()
        {
            var Context = Web.Context;
            Web.Navigation.UseShared = true;
            Web.Update();
            Web.Context.Load(Web, w=> w.Title, x => x.ServerRelativeUrl);
            Context.ExecuteQuery();
            WriteObject(Web);
        }
    }


    /// <summary>
    /// Activates Sandboxed solutions
    /// </summary>
    [Cmdlet(VerbsLifecycle.Install, "SPOSolution")]
    public class InstallSPOSolution : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string Solution { get; set; }

        protected override void ProcessRecord()
        {
            var file = Site.RootWeb.GetFileByServerRelativeUrl(Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/solutions/" + Solution);
            Site.Context.Load(file.ListItemAllFields);
            Site.Context.ExecuteQuery();
            SPHelpers.CallActivateAspx((ClientContext)Site.Context, file.ListItemAllFields.Id, "Activate");
            WriteObject(Site);
        }
    }

    /// <summary>
    /// Deactivates Sandboxed solutions
    /// </summary>
    [Cmdlet(VerbsLifecycle.Uninstall, "SPOSolution")]
    public class UninstallSPOSolution : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string Solution { get; set; }

        protected override void ProcessRecord()
        {
            var file = Site.RootWeb.GetFileByServerRelativeUrl(Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/solutions/" + Solution);
            Site.Context.Load(file.ListItemAllFields);
            Site.Context.ExecuteQuery();
            SPHelpers.CallActivateAspx((ClientContext)Site.Context, file.ListItemAllFields.Id, "Deactivate");
            WriteObject(Site);
        }
    }

    /// <summary>
    /// Upgrades Sandboxed solutions
    /// </summary>
    [Cmdlet(VerbsData.Update, "SPOSolution")]
    public class UpdateSPOSolution : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Site Site { get; set; }

        [Parameter(Mandatory = true)]
        public string Solution { get; set; }

        protected override void ProcessRecord()
        {
            var file = Site.RootWeb.GetFileByServerRelativeUrl(Site.ServerRelativeUrl.TrimEnd('/') + "/_catalogs/solutions/" + Solution);
            Site.Context.Load(file.ListItemAllFields);
            Site.Context.ExecuteQuery();
            SPHelpers.CallActivateAspx((ClientContext)Site.Context, file.ListItemAllFields.Id, "Upgrade");
            WriteObject(Site);
        }
    }

    /// <summary>
    /// Gets a NavigationNodeCollection from the Web
    /// </summary>
    [Cmdlet(VerbsCommon.Get, "SPONavigation")]
    public class GetSPONavigation : Cmdlet
    {

        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public Web Web { get; set; }

        [Parameter]
        public SwitchParameter Current { get; set; }

        [Parameter]
        public SwitchParameter Search { get; set; }

        protected override void ProcessRecord()
        {
            var search = Web.Navigation.GetNodeById(1040);
            Web.Context.Load(Web.Navigation.QuickLaunch);
            Web.Context.Load(Web.Navigation.TopNavigationBar);
            Web.Context.Load(search);
            Web.Context.ExecuteQuery();
            if (Current.IsPresent)
            {
                WriteObject(Web.Navigation.QuickLaunch);
            }
            else if(Search.IsPresent)
            {
                Web.Context.Load(search.Children);
                Web.Context.ExecuteQuery();
                WriteObject(search.Children);
            }
            else
            {
                WriteObject(Web.Navigation.TopNavigationBar);
            }
        }
    }

    /// <summary>
    /// Clears a navigation collection
    /// </summary>
    [Cmdlet(VerbsCommon.Clear, "SPONavigation")]
    public class ClearSPONavigation : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public NavigationNodeCollection NodeCollection { get; set; }

        protected override void ProcessRecord()
        {
            var Context = NodeCollection.Context;
            for (var numItems = NodeCollection.Count; numItems > 0; numItems--)
            {
                NodeCollection[numItems - 1].DeleteObject();
            }
            Context.Load(NodeCollection);
            Context.ExecuteQuery();
            WriteObject(NodeCollection);
        }
    }

    /// <summary>
    /// Adds a navigation node to a NavigationNodeCollection
    /// </summary>
    [Cmdlet(VerbsCommon.Add, "SPONavigationItem")]
    public class AddSPONavigationItem : Cmdlet
    {
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public NavigationNodeCollection Collection { get; set; }

        [Parameter(Mandatory = true)]
        public String Title { get; set;}

        [Parameter(Mandatory = true)]
        public String Url { get; set; }

        [Parameter]
        public SwitchParameter External { get; set; }

        protected override void ProcessRecord()
        {
            var Context = (ClientContext) Collection.Context;
            //add a navigation node creation item to a collection
            NavigationNodeCreationInformation ciNavicationNode = new NavigationNodeCreationInformation
                {
                    Title = Title,
                    Url = Url,
                    AsLastNode = true,
                    IsExternal = External.IsPresent
                };
            // Create node as the last node in the collection.
            Collection.Add(ciNavicationNode);
            Context.Load(Collection.Last());
            //Load up dem children so you can add to the hierachy.
            Context.Load(Collection.Last().Children);
            Context.ExecuteQuery();
            //Write out the most recent node.
            WriteObject(Collection); 
        }
    }

    /// <summary>
    /// Removes all NavigationNodes and children based on title
    /// </summary>
    [Cmdlet(VerbsCommon.Remove, "SPONavigationNodesByName")]
    public class RemoveSPONavigationNodesByName : Cmdlet
    {

        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public NavigationNodeCollection Collection { get; set; }

        [Parameter(Mandatory = true)]
        public string Name { get; set; }

        protected override void ProcessRecord()
        {
           RecurseAndDeleteNodes(Collection);
        }
        public void RecurseAndDeleteNodes(NavigationNodeCollection nodes)
        {
            Collection.Context.Load(nodes);
            Collection.Context.ExecuteQuery();
            for (var numItems = nodes.Count; numItems > 0; numItems--)
            {
                if (nodes[numItems - 1].Title == Name)
                {
                    nodes[numItems - 1].DeleteObject();
                }
                else
                {
                    RecurseAndDeleteNodes(nodes[numItems - 1].Children);
                }
            }
        }
    }

    public static class SPHelpers
    {
        public static int GetListTemplate(String template)
        {
            switch (template)
            {
                case "Link":
                    return (int)ListTemplateType.Links;
                case "Document":
                    return (int)ListTemplateType.DocumentLibrary;
                case "Form":
                    return (int)ListTemplateType.XMLForm;
                case "Event":
                    return (int)ListTemplateType.Events;
                case "Task":
                    return (int)ListTemplateType.Tasks;
                case "Survey":
                    return (int)ListTemplateType.Survey;
                case "Contact":
                    return (int)ListTemplateType.Contacts;
                case "Image":
                    return (int)ListTemplateType.PictureLibrary;
                case "Announcement":
                    return (int)ListTemplateType.Announcements;
                case "List":
                    return (int)ListTemplateType.GenericList;
                case "Posts":
                    return (int)ListTemplateType.Posts;
                default:
                    return int.Parse(template);

            }
        }

        /// <summary>
        /// To reduce duplication in activation/upgrade/deactivation of solutions
        /// </summary>
        /// <param name="context"></param>
        /// <param name="solutionListItemId"></param>
        /// <param name="action">Can be activate/deactivate/upgrade</param>
        public static void CallActivateAspx(ClientContext context, int solutionListItemId, string action)
        {
            var host = new Uri(context.Url);
            var requestUrl = string.Format("{0}/_catalogs/solutions/Forms/Activate.aspx?Op={1}&ID={2}", context.Url, action.Substring(0, 3).ToUpper(), solutionListItemId);
            var claimsClient = new SPOWebClient(host, ((SharePointOnlineCredentials)context.Credentials));
            var reponse = claimsClient.DownloadString(requestUrl);
            var postData = new NameValueCollection();
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(reponse);
            foreach (HtmlNode input in doc.DocumentNode.SelectNodes("//input"))
            {
                var name = input.Attributes["name"];
                if (name != null)
                {
                    if (name.Value == "__EVENTVALIDATION" || name.Value == "__REQUESTDIGEST" ||
                        name.Value == "__VIEWSTATE")
                    {
                        postData.Add(input.Attributes["name"].Value,
                                     input.Attributes["value"] == null ? "" : input.Attributes["value"].Value);
                    }
                }
            }
            var node = doc.DocumentNode.SelectNodes("//td/a").FirstOrDefault(n => n.InnerText == action);
            postData.Add("__EVENTTARGET", node.Attributes["href"].Value.Replace("javascript:__doPostBack(&#39;", "").Replace("&#39;,&#39;&#39;)", ""));

            claimsClient.Headers.Add(HttpRequestHeader.Host, context.Url.Replace("https://", "").Split('/').First());
            claimsClient.Headers.Add(HttpRequestHeader.Referer, requestUrl);
            claimsClient.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            claimsClient.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
            claimsClient.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.5");
            claimsClient.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0");
            //Do the post
            claimsClient.UploadValues(requestUrl, postData);
        }

        public static void CallContentTypePublishing(ClientContext context, string contentTypeId, string action)
        {
            var host = new Uri(context.Url);
            var requestUrl = string.Format("{0}/_layouts/15/managectpublishing.aspx?ctype={1}", context.Url, contentTypeId);
            var claimsClient = new SPOWebClient(host, ((SharePointOnlineCredentials)context.Credentials));
            var reponse = claimsClient.DownloadString(requestUrl);
            var postData = new NameValueCollection();
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(reponse);
            foreach (HtmlNode input in doc.DocumentNode.SelectNodes("//input"))
            {
                var name = input.Attributes["name"];
                if (name != null)
                {
                    if (name.Value == "__EVENTVALIDATION" || name.Value == "__REQUESTDIGEST" ||
                        name.Value == "__VIEWSTATE")
                    {
                        postData.Add(input.Attributes["name"].Value,
                                     input.Attributes["value"] == null ? "" : input.Attributes["value"].Value);
                    }
                }
            }
            postData.Add("ctl00$PlaceHolderMain$actionSection$RadioGroupAction", action+"Button");
            postData.Add("ctl00$PlaceHolderMain$ctl00$RptControls$okButton", "OK");

            claimsClient.Headers.Add(HttpRequestHeader.Host, context.Url.Replace("https://", "").Split('/').First());
            claimsClient.Headers.Add(HttpRequestHeader.Referer, requestUrl);
            claimsClient.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            claimsClient.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate");
            claimsClient.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.5");
            claimsClient.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0");
            //Do the post
            claimsClient.UploadValues(requestUrl, postData);
        }
    }
}
